a[i]=a[j];
*px = *py;
class Base{ };
class Derived: public Base{ };
void doSomething(const Base& rb, Derived* pd);
위와 같은 코드에서 i==j 혹은 px==py인 경우, 자기 대입을 하게 된다.
rb와 *pd가 같은 객체일 수 있다.
(자기 대입은 적법한 코드임 이를 허용하도록 구현해 주어야 한다.)
자기 대입을 하게 되었을 때, 중복 참조(aliasing)이 발생할 수 있다.
class Bitmap{ };
class Widget{
private:
Bitmap* pb;
};
Widget& Widget::operator=(const Widget& rhs){
delete pb;
pb=new Bitmap(*rhs.pb);
return *this;
}
위에서 *rhs.pb와 *pb가 동일한 개체일 경우, 문제가 발생한다.
이와 같은 상황을 막기 위해 일치성 검사(identity test)를 실행해 줘야 한다.
Widget& Widget::operator=(const Widget& rhs){
if(this==&rhs) return *this;
delete pb;
pb=new Bitmap(*rhs.pb);
return *this;
}
위에 코드에서 new는 예외를 발생시킬 수 있다.
아래와 같이 코드를 작성하면, new에서 예외를 발생시키더라도, 사본을 통해 동일한 동작을 수행할 수 있다.
(추가적인 일치성 검사도 필요하지 않음)
Widget& Widget::operator=(const Widget& rhs){
Bitmap* pOrig=pb;
pb=new Bitmap(*rhs.pb);
delete pOrig;
return *this;
}
copy and swap
class Widget{
void swap(Widget& rhs);
};
Widget& Widget::operator=(const Widget& rhs){
Widget temp(rhs);
swap(temp);
return *this;
}
값으로 인자를 전달받을 때, 사본을 생성 후 복사하기 때문에 위의 operator=와아래 operator=는 동일하게 동작한다.
Widget& Widget::operator=(Widget rhs){
swap(rhs);
return *this;
}